<html>
	<head>
		<meta charset="ISO8859-1">
		<title>ScribeFire Test Suite</title>
		<link rel="stylesheet" href="http://code.jquery.com/qunit/git/qunit.css" type="text/css" media="screen" />
		<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
		<script type="text/javascript" src="http://code.jquery.com/qunit/git/qunit.js"></script>
		<script type="text/javascript" src="tests.config.js"></script>
		<script type="text/javascript">
			if (typeof opera != "undefined") {
				var platform = "presto";
				var browser = "opera";
			}
			else if (typeof Components != 'undefined') {
				var platform = "gecko";
				var browser = 'firefox';
			}
			else {
				var platform = "webkit";

				if (typeof chrome != 'undefined') {
					var browser = 'chrome';
				}
				else {
					var browser = 'safari';
				}
			}
		</script>
		<script type="text/javascript" src="io.js"></script><!-- FIREFOX ONLY -->
		<script type="text/javascript" src="messages.js"></script><!-- SAFARI ONLY -->
		<script type="text/javascript" src="util.js"></script>
		<script type="text/javascript" src="xmlrpc.js"></script>
		<script type="text/javascript" src="apis.js"></script>
		<script type="text/javascript" src="scribefire.js"></script>
		<script type="text/javascript" src="zemanta.js"></script>
		<script type="text/javascript" src="vendor/jquery-ui.js"></script>
		<script type="text/javascript" src="vendor/jquery-resize.js"></script>
		<script type="text/javascript" src="vendor/parseUri.js"></script>
		<script type="text/javascript" src="vendor/facebox.js"></script>
		<script type="text/javascript" src="lib/tiny_mce/tiny_mce_src.js"></script>
		<script type="text/javascript" src="lib/persist.js"></script>
		<script type="text/javascript" src="lib/keyboard.js"></script>
		<script type="text/javascript" src="vendor/wordpress.js"></script>
		<script type="text/javascript" src="migrate.js"></script>
		<script type="text/javascript" src="vendor/jquery-oembed.js"></script>
		<script type="text/javascript" src="lib/upload.js"></script>
		<script type="text/javascript" src="adbull.js"></script>
		
		<script type="text/javascript">
			function run() {
				module("util.js");
				
				test("util.pad", function () {
					deepEqual(pad(4), "04");
					deepEqual(pad(10), "10");
					deepEqual(pad(100), "100");
					deepEqual(pad(0), "00");
					deepEqual(pad(-1), "00");
				});
				
				test("Array.unique", function () {
					var array = [1, 2, 3, 4, 5, 4, 3, 2, 1];
					array.unique();
					
					deepEqual(array, [1, 2, 3, 4, 5]);

					var array = [1];
					array.unique();
					
					deepEqual(array, [1]);
					
					var array = [1, "1", 2, "abc", 0, false];
					array.unique();
					
					deepEqual(array, [1, "1", 2, "abc", 0, false]);
				});
				
				test("util.resolveHref", function () {
					equal(resolveHref("http://google.com/", "abc/def/ghi"), "http://google.com/abc/def/ghi");
					equal(resolveHref("http://google.com/", "/abc/def/ghi"), "http://google.com/abc/def/ghi");
					equal(resolveHref("http://google.com/", "//abc/def/ghi"), "http://abc/def/ghi");
					equal(resolveHref("http://google.com/", "http://abc.com/def/ghi"), "http://abc.com/def/ghi");
					equal(resolveHref("http://google.com/xxx/yyy", "abc/def/ghi"), "http://google.com/xxx/abc/def/ghi");
					equal(resolveHref("http://google.com/xxx/yyy/", "abc/def/ghi"), "http://google.com/xxx/yyy/abc/def/ghi");
					equal(resolveHref("http://google.com/xxx/yyy", "/abc/def/ghi"), "http://google.com/abc/def/ghi");
				});
				
				module("xmlrpc.js");
				
				test("xmlrpc.convertToXML", function () {
					equal(XMLRPC_LIB.convertToXML("def"), "<string><![CDATA[def]]></string>");
					
					// @todo Check support. equal(XMLRPC_LIB.convertToXML(true), "<boolean>1</boolean>");
					// @todo Check support. equal(XMLRPC_LIB.convertToXML(false), "<boolean>0</boolean>");
					
					var date = new Date();
					date.setTime(5000);
					
					equal(XMLRPC_LIB.convertToXML(date), "<dateTime.iso8601>19700101T00:00:05Z</dateTime.iso8601>");
					equal(XMLRPC_LIB.convertToXML(123), "<int>123</int>");
					equal(XMLRPC_LIB.convertToXML(0), "<int>0</int>");
					equal(XMLRPC_LIB.convertToXML(-4), "<int>-4</int>");
					equal(XMLRPC_LIB.convertToXML(12.4), "<double>12.4</double>");
					equal(XMLRPC_LIB.convertToXML(-12.4), "<double>-12.4</double>");
					equal(XMLRPC_LIB.convertToXML([ 1, "2", 3.5, date ]), "<array><data><value><int>1</int></value><value><string><![CDATA[2]]></string></value><value><double>3.5</double></value><value><dateTime.iso8601>19700101T00:00:05Z</dateTime.iso8601></value></data></array>");
					equal(XMLRPC_LIB.convertToXML([ 1, [ 5 ]]), "<array><data><value><int>1</int></value><value><array><data><value><int>5</int></value></data></array></value></data></array>");
					equal(XMLRPC_LIB.convertToXML({ "a" : 4, "b" : "thirty" }), "<struct><member><name><![CDATA[a]]></name><value><int>4</int></value></member><member><name><![CDATA[b]]></name><value><string><![CDATA[thirty]]></string></value></member></struct>");
				});
				
				test("xmlrpc.makeXML", function () {
					equal(XMLRPC_LIB.makeXML("abc"), '<?xml version="1.0" encoding="UTF-8" ?>' + "\n" + '<methodCall><methodName><![CDATA[abc]]></methodName></methodCall>');
					equal(XMLRPC_LIB.makeXML("abc", [ "def" ]), '<?xml version="1.0" encoding="UTF-8" ?>' + "\n" + '<methodCall><methodName><![CDATA[abc]]></methodName><params><param><value><string><![CDATA[def]]></string></value></param></params></methodCall>');
				});
				
				test("xmlrpc.XMLToObject", function () {
					deepEqual(XMLRPC_LIB.XMLToObject($("<int>01234</int>")), 1234);
					deepEqual(XMLRPC_LIB.XMLToObject($("<int>567</int>")), 567);
					deepEqual(XMLRPC_LIB.XMLToObject($("<i4>01234</i4>")), 1234);
					deepEqual(XMLRPC_LIB.XMLToObject($("<i4>567</i4>")), 567);
					deepEqual(XMLRPC_LIB.XMLToObject($("<boolean>1</boolean>")), true);
					deepEqual(XMLRPC_LIB.XMLToObject($("<boolean>0</boolean>")), false);
					deepEqual(XMLRPC_LIB.XMLToObject($("<foo>true</foo>")), undefined);
					deepEqual(XMLRPC_LIB.XMLToObject($("<string>hello there</string>")), "hello there");
					deepEqual(XMLRPC_LIB.XMLToObject($("<double>567</double>")), 567);
					deepEqual(XMLRPC_LIB.XMLToObject($("<double>567.435555</double>")), 567.435555);
					deepEqual(XMLRPC_LIB.XMLToObject($("<struct><member><name>abc</name><value><int>123</int></value></member><member><name>def</name><value><double>456.7</double></value></member></struct>")), { "abc" : 123, "def" : 456.7 });
					deepEqual(XMLRPC_LIB.XMLToObject($("<array><data><value><int>123</int></value><value><double>15.2</double></value><value><string>hi there</string></value></data></array>")), [ 123, 15.2, "hi there" ]);
				});
				
				test("xmlrpc.iso8601Format", function () {
					var date = new Date();
					date.setTime(5000);
					
					equal(XMLRPC_LIB.iso8601Format(date), "19700101T00:00:05Z");
					
					date.setTime(-10000);
					
					equal(XMLRPC_LIB.iso8601Format(date), "19691231T23:59:50Z");
				});
				
				module("getBlogMetaData");
				
				var blogs = {
					"cfinke.wordpress.com" : {
						url : "http://cfinke.wordpress.com/",
						type : "wordpress",
						apiUrl : "http://cfinke.wordpress.com/xmlrpc.php"
					},
					"http://foo.tumblr.com" : {
						url : "http://foo.tumblr.com/",
						type : "tumblr",
						apiUrl : "http://www.tumblr.com/api"
					},
					"foo.posterous.com/" : {
						url : "http://foo.posterous.com/",
						type : "posterous",
						apiUrl : "http://posterous.com/api"
					},
					"foo.xanga.com/" : {
						url : "http://foo.xanga.com/",
						type : "metaweblog",
						apiUrl : "http://api.xanga.com/metaweblogapi"
					},
					"chrisfinke.com" : {
						url : "http://chrisfinke.com/",
						type : "wordpress",
						apiUrl : "http://www.chrisfinke.com/xmlrpc.php"
					},
					"http://mywifeandyourmom.blogspot.com" : {
						url : "http://mywifeandyourmom.blogspot.com/",
						type : "blogger",
						atomAPIs : { "service.post" : "http://www.blogger.com/feeds/5123683377216095177/posts/default", "service.feed" : "http://www.blogger.com/feeds/5123683377216095177/posts/default" },
						apiUrl : "http://www.blogger.com/feeds/5123683377216095177/posts/default"
					},
					"p.estebanglas.com" : {
						url : "http://p.estebanglas.com/",
						type : "posterous",
						apiUrl : "http://posterous.com/api"
					}
				};
				
				for (var i in blogs) {
					(function (blogKey, blogData) {
						test("scribefire.getBlogMetaData => " + blogKey, function () {
							stop();
							
							SCRIBEFIRE.getBlogMetaData(
								blogKey,
								function success(data) { 
									for (var x in blogData) {
										deepEqual(data[x], blogData[x]);
									}
									
									start();
								}, 
								function failure(msg) { 
									ok(false, msg);
									start();
								}
							);
						});
					})(i, blogs[i]);
				}
				
				module("publish");
				
				if (typeof passwords != 'undefined' && document.location.href.indexOf("publish") != -1) {
					var now = new Date();
					
					var postTemplates = {
						"published" : {
							title : now.getTime().toString(),
							content : "The timestamp is now " + now.getTime(),
							tags : "tag1, tag2, tag3",
							draft : false,
							slug : "this-is-the-slug-" + now.getTime(),
							"private" : true,
							type : "posts"
						},
						"draft" : {
							title : (now.getTime() + 5000).toString(),
							content : "The timestamp is now " + (now.getTime() + 5000),
							tags : "",
							draft : true,
							slug : "this-is-the-slug-" + (now.getTime() + 5000),
							"private" : false,
							type : "posts"
						},
						"scheduled" : {
							title : (now.getTime() + 10000).toString(),
							content : "The timestamp is now " + (now.getTime() + 10000),
							tags : "",
							draft : false,
							slug : "this-is-the-slug-" + (now.getTime() + 10000),
							"private" : false,
							type : "posts",
							timestamp : (function () { var timestamp = new Date(2012, 5, 15, 6, 12, 0, 0); return timestamp; })()
						}
					};
					
					var category = "new-cat-" + Math.random();
					var categoryObject = null;
					
					for (var aService in passwords) {
						for (postKey in postTemplates) {
							(function (service, originalPost, aPostKey) {
								test(
									"api." + service + " (" + aPostKey + ")",
									function () {
										var api = getBlogAPI(passwords[service].type, passwords[service].apiUrl).init(passwords[service]);
										
										if (originalPost.draft && !api.ui.draft) {
											return;
										}
										
										stop();
									
										var thePostID = null;
										var thePost = null;
									
										api.addCategory(
											{ name : category },
											function (data) {
												categoryObject = data;
												
												if (categoryObject) {
													originalPost.categories = [ categoryObject.name ];
												}
												
												api.publish(
													originalPost, 
													function (data) {
														ok("id" in data && data.id, "Publish returned an ID.");

														thePostID = data.id;
														
														api.getPosts(
															{}, 
															function (data) {
																if (typeof data == 'object' && "Posts" in data) data = data.Posts;
																
																for (var i = 0, _len = data.length; i < _len; i++) {
																	var post = data[i];
																	
																	if (post.id == thePostID) {
																		thePost = post;
																		thePost.type = originalPost.type;
																		break;
																	}
																}
																
																if (api.ui.getPosts) {
																	ok(thePost, "Found the published post in the list of recent posts.");
																}
																else {
																	thePost = originalPost;
																	thePost.id = thePostID;
																	thePost.published = !originalPost.draft;
																}
																
																if (thePost) {
																	if (api.ui.categories) {
																		if (!("categories" in thePost)) {
																			ok(false, "Categories missing from post.");
																		}
																		else {
																			equal(thePost.categories.length, originalPost.categories.length, "Number of categories");
																			equal(thePost.categories[0], originalPost.categories[0], "Equal category ID");
																		}
																	}
																	
																	if (api.ui.draft) {
																		equal(thePost.published, !originalPost.draft, "Published status");
																	}
										
																	if (api.ui.tags) {
																		equal(thePost.tags, originalPost.tags, "Tags");
																	}
										
																	if (api.ui.slug) {
																		equal(thePost.slug, originalPost.slug, "Slug");
																	}
																	
																	if (api.ui["private"]) {
																		equal(thePost["private"], originalPost["private"], "Privacy");
																	}
																	
																	if (api.ui.timestamp && "timestamp" in originalPost && service != "livejournal") { // LJ's scheduling support is broken.
																		equal(
																			thePost.timestamp.getTime(), 
																			originalPost.timestamp.getTime(), 
																			"Timestamp");
																	}
																	
																	equal(thePost.title, originalPost.title, "Title");
																	equal(thePost.content.replace(/<\/?p>/g, ''), originalPost.content, "Content");
										
																	var newNow = new Date();
																	
																	originalPost.title = "New title: " + newNow.getTime();
																	originalPost.content = "New body: " + newNow.getTime();
																	
																	// Put the original parameters back into the object
																	// This gets things like .draft set properly, since it's not returned
																	// as a field from the API, even though I should have done that.
																	for (var i in originalPost) thePost[i] = originalPost[i];
																	
																	api.publish(
																		thePost, 
																		function (data) {
																			ok("id" in data && data.id, "The edit returned an ID.");
																			
																			// Check that this was saved successfully.
																			
																			api.getPosts(
																				{}, 
																				function (data) {
																					if (typeof data == 'object' && "Posts" in data) data = data.Posts;
																					
																					thePost = null;
																					
																					for (var i = 0, _len = data.length; i < _len; i++) {
																						var post = data[i];

																						if (post.id == thePostID) {
																							thePost = post;
																							thePost.type = originalPost.type;
																							break;
																						}
																					}

																					if (api.ui.getPosts) {
																						ok(thePost, "[Edit] Found the published post in the list of recent posts.");
																					}
																					else {
																						thePost = originalPost;
																						thePost.id = thePostID;
																						thePost.published = !originalPost.draft;
																					}

																					if (thePost) {
																						if (api.ui.categories) {
																							if (!("categories" in thePost)) {
																								ok(false, "[Edit] Categories missing from post.");
																							}
																							else {
																								equal(thePost.categories.length, originalPost.categories.length, "[Edit] Number of categories");
																								equal(thePost.categories[0], originalPost.categories[0], "[Edit] Equal category ID");
																							}
																						}

																						if (api.ui.draft) {
																							equal(thePost.published, !originalPost.draft, "[Edit] Published status");
																						}

																						if (api.ui.tags) {
																							equal(thePost.tags, originalPost.tags, "[Edit] Tags");
																						}

																						if (api.ui.slug) {
																							equal(thePost.slug, originalPost.slug, "[Edit] Slug");
																						}

																						if (api.ui["private"]) {
																							equal(thePost["private"], originalPost["private"], "[Edit] Privacy");
																						}
																						
																						if (api.ui.timestamp && "timestamp" in originalPost && service != "livejournal") { // LJ's scheduling support is broken.
																							equal(
																								thePost.timestamp.getTime(), 
																								originalPost.timestamp.getTime(), "[Edit] Timestamp");
																						}

																						equal(thePost.title, originalPost.title, "[Edit] Title");
																						equal(thePost.content.replace(/<\/?p>/g, ''), originalPost.content, "[Edit] Content");
//																						ok(thePost.content == originalPost.content || ("<p>" + originalPost.content + "</p>") == thePost.content, "[Edit] Content");
																						
																						// Put the original parameters back into the object
																						// This gets things like .draft set properly, since it's not returned
																						// as a field from the API, even though I should have done that.
																						for (var i in originalPost) thePost[i] = originalPost[i];
																						
																						api.deletePost(
																							thePost, 
																							function (data) {
																								ok(true, "Post deleted.");
																								start();
																							},
																							function (data) {
																								ok(false, "Post not deleted.");
																								start();
																							}
																						);
																					}
																				},
																				function (data) {
																					ok(false, data.msg);
																					start();
																				}
																			);
																		},
																		function (data) {
																			ok(false, data.msg);
																			start();
																		}
																	);
																}
																else {
																	start();
																}
															},
															function (data) {
																ok(false, data.msg);
																start();
															}
														);
													},
													function (data) {
														ok(false, data.msg);
														start();
													}
												);
											}
										);
									}
								);
							})(aService, postTemplates[postKey], postKey);
						}
					}
				}
			}
				
		</script>
	</head>
	<body onload="run();">
		<h1 id="qunit-header">ScribeFire Test Suite</h1>
		<h2 id="qunit-banner"></h2>
		<div id="qunit-testrunner-toolbar"></div>
		<h2 id="qunit-userAgent"></h2>
		<ol id="qunit-tests"></ol>
		<script type="text/javascript" src="lib/platform.js"></script>
		<script type="text/javascript" src="lib/i18n.js"></script>
	</body>
</html>